//! 泛型系统和类型约束机制
//!
//! 设计原则：
//! - 支持泛型类型定义和实例化
//! - 实现类型约束检查
//! - 支持泛型函数和泛型类
//! - 提供类型参数推断

use crate::ast::SourceLocation;
use crate::type_checker::TypeInfo;
use crate::type_system::TypeDefinition;
use crate::type_system::type_hierarchy::BasicType;
use std::collections::HashMap;
use std::sync::Arc;

/// 泛型参数
#[derive(Debug, Clone, PartialEq)]
pub struct GenericParameter {
    /// 参数名称
    pub name: String,
    /// 类型约束
    pub constraints: Vec<TypeConstraint>,
    /// 默认值（可选）
    pub default: Option<TypeInfo>,
    /// 位置信息
    pub location: Option<SourceLocation>,
}

/// 类型约束
#[derive(Debug, Clone, PartialEq)]
pub enum TypeConstraint {
    /// 类型边界约束
    TypeBound(TypeBound),
    /// 接口约束
    Interface(String),
    /// 特质约束
    Trait(String),
    /// 相等约束
    Equal(TypeInfo),
    /// 子类型约束
    Subtype(TypeInfo),
}

/// 类型边界
#[derive(Debug, Clone, PartialEq)]
pub enum TypeBound {
    /// 上界（必须是某类型的子类型）
    Upper(TypeInfo),
    /// 下界（必须是某类型的父类型）
    Lower(TypeInfo),
    /// 精确类型
    Exact(TypeInfo),
}

/// 泛型类型定义
#[derive(Debug, Clone)]
pub struct GenericType {
    /// 类型名称
    pub name: String,
    /// 泛型参数
    pub parameters: Vec<GenericParameter>,
    /// 类型定义
    pub definition: TypeDefinition,
    /// 位置信息
    pub location: Option<SourceLocation>,
}

/// 泛型实例化
#[derive(Debug, Clone)]
pub struct GenericInstance {
    /// 原始泛型类型
    pub generic_type: Arc<GenericType>,
    /// 类型参数映射
    pub type_arguments: HashMap<String, TypeInfo>,
    /// 实例化后的类型
    pub instantiated_type: TypeDefinition,
}

/// 泛型系统
pub struct GenericSystem {
    /// 泛型类型定义
    generic_types: HashMap<String, Arc<GenericType>>,
    /// 泛型实例缓存
    instances: HashMap<String, Arc<GenericInstance>>,
    /// 类型约束检查器
    constraint_checker: TypeConstraintChecker,
}

impl GenericSystem {
    /// 创建新的泛型系统
    pub fn new() -> Self {
        Self {
            generic_types: HashMap::new(),
            instances: HashMap::new(),
            constraint_checker: TypeConstraintChecker::new(),
        }
    }

    /// 定义泛型类型
    pub fn define_generic_type(&mut self, generic_type: GenericType) -> Result<(), String> {
        let name = generic_type.name.clone();

        // 检查泛型参数名称是否唯一
        let mut param_names = HashMap::new();
        for param in &generic_type.parameters {
            if param_names.contains_key(&param.name) {
                return Err(format!("重复的泛型参数名称: {}", param.name));
            }
            param_names.insert(param.name.clone(), true);
        }

        self.generic_types.insert(name, Arc::new(generic_type));
        Ok(())
    }

    /// 实例化泛型类型
    pub fn instantiate_generic(
        &mut self,
        generic_name: &str,
        type_arguments: HashMap<String, TypeInfo>,
        _location: Option<SourceLocation>,
    ) -> Result<Arc<GenericInstance>, String> {
        // 获取泛型类型定义
        let generic_type = self
            .generic_types
            .get(generic_name)
            .ok_or_else(|| format!("未定义的泛型类型: {}", generic_name))?;

        // 检查类型参数数量
        if type_arguments.len() != generic_type.parameters.len() {
            return Err(format!(
                "类型参数数量不匹配: 期望 {}, 实际 {}",
                generic_type.parameters.len(),
                type_arguments.len()
            ));
        }

        // 检查类型约束
        for param in &generic_type.parameters {
            if let Some(arg_type) = type_arguments.get(&param.name) {
                for constraint in &param.constraints {
                    self.constraint_checker
                        .check_constraint(arg_type, constraint, &self)?;
                }
            } else if param.default.is_none() {
                return Err(format!("缺少类型参数: {}", param.name));
            }
        }

        // 创建实例化缓存键
        let cache_key = self.create_instance_key(generic_name, &type_arguments);

        // 检查缓存
        if let Some(cached_instance) = self.instances.get(&cache_key) {
            return Ok(cached_instance.clone());
        }

        // 创建新的实例
        let instance = Arc::new(GenericInstance {
            generic_type: generic_type.clone(),
            type_arguments: type_arguments.clone(),
            instantiated_type: self.create_instantiated_type(generic_type, &type_arguments)?,
        });

        // 缓存实例
        self.instances.insert(cache_key, instance.clone());

        Ok(instance)
    }

    /// 创建实例化后的类型
    fn create_instantiated_type(
        &self,
        _generic_type: &Arc<GenericType>,
        _type_arguments: &HashMap<String, TypeInfo>,
    ) -> Result<TypeDefinition, String> {
        // 这里需要根据具体类型定义来实例化
        // 简化实现：直接返回基础类型
        Ok(TypeDefinition::Basic(BasicType::Any))
    }

    /// 创建实例缓存键
    fn create_instance_key(
        &self,
        generic_name: &str,
        type_arguments: &HashMap<String, TypeInfo>,
    ) -> String {
        let mut parts = vec![generic_name.to_string()];
        let mut keys: Vec<_> = type_arguments.keys().collect();
        keys.sort();

        for key in keys {
            if let Some(value) = type_arguments.get(key) {
                parts.push(format!("{}:{}", key, value.to_string()));
            }
        }

        parts.join("_")
    }

    /// 获取泛型类型
    pub fn get_generic_type(&self, name: &str) -> Option<Arc<GenericType>> {
        self.generic_types.get(name).cloned()
    }

    /// 获取泛型实例
    pub fn get_instance(&self, cache_key: &str) -> Option<Arc<GenericInstance>> {
        self.instances.get(cache_key).cloned()
    }
}

/// 类型约束检查器
pub struct TypeConstraintChecker {
    /// 约束规则
    rules: HashMap<String, Box<dyn ConstraintRule>>,
}

impl TypeConstraintChecker {
    /// 创建新的约束检查器
    pub fn new() -> Self {
        let mut checker = Self {
            rules: HashMap::new(),
        };

        // 注册默认约束规则
        checker.register_default_rules();
        checker
    }

    /// 注册默认约束规则
    fn register_default_rules(&mut self) {
        self.rules
            .insert("type_bound".to_string(), Box::new(TypeBoundRule));
        self.rules
            .insert("interface".to_string(), Box::new(InterfaceRule));
        self.rules.insert("trait".to_string(), Box::new(TraitRule));
        self.rules.insert("equal".to_string(), Box::new(EqualRule));
        self.rules
            .insert("subtype".to_string(), Box::new(SubtypeRule));
    }

    /// 检查类型约束
    pub fn check_constraint(
        &self,
        actual_type: &TypeInfo,
        constraint: &TypeConstraint,
        generic_system: &GenericSystem,
    ) -> Result<(), String> {
        match constraint {
            TypeConstraint::TypeBound(bound) => {
                self.check_type_bound(actual_type, bound, generic_system)
            }
            TypeConstraint::Interface(interface_name) => {
                self.check_interface(actual_type, interface_name)
            }
            TypeConstraint::Trait(trait_name) => self.check_trait(actual_type, trait_name),
            TypeConstraint::Equal(expected_type) => self.check_equal(actual_type, expected_type),
            TypeConstraint::Subtype(expected_type) => {
                self.check_subtype(actual_type, expected_type)
            }
        }
    }

    /// 检查类型边界
    fn check_type_bound(
        &self,
        actual_type: &TypeInfo,
        bound: &TypeBound,
        _generic_system: &GenericSystem,
    ) -> Result<(), String> {
        match bound {
            TypeBound::Upper(expected_type) => {
                if !self.is_subtype(actual_type, expected_type) {
                    return Err(format!(
                        "类型 {} 不是类型 {} 的子类型",
                        actual_type.to_string(),
                        expected_type.to_string()
                    ));
                }
            }
            TypeBound::Lower(expected_type) => {
                if !self.is_subtype(expected_type, actual_type) {
                    return Err(format!(
                        "类型 {} 不是类型 {} 的父类型",
                        actual_type.to_string(),
                        expected_type.to_string()
                    ));
                }
            }
            TypeBound::Exact(expected_type) => {
                if actual_type != expected_type {
                    return Err(format!(
                        "类型 {} 与期望类型 {} 不匹配",
                        actual_type.to_string(),
                        expected_type.to_string()
                    ));
                }
            }
        }
        Ok(())
    }

    /// 检查接口
    fn check_interface(
        &self,
        _actual_type: &TypeInfo,
        _interface_name: &str,
    ) -> Result<(), String> {
        // 简化实现：总是通过
        Ok(())
    }

    /// 检查特质
    fn check_trait(&self, _actual_type: &TypeInfo, _trait_name: &str) -> Result<(), String> {
        // 简化实现：总是通过
        Ok(())
    }

    /// 检查相等性
    fn check_equal(&self, actual_type: &TypeInfo, expected_type: &TypeInfo) -> Result<(), String> {
        if actual_type != expected_type {
            return Err(format!(
                "类型 {} 与期望类型 {} 不相等",
                actual_type.to_string(),
                expected_type.to_string()
            ));
        }
        Ok(())
    }

    /// 检查子类型关系
    fn check_subtype(
        &self,
        actual_type: &TypeInfo,
        expected_type: &TypeInfo,
    ) -> Result<(), String> {
        if !self.is_subtype(actual_type, expected_type) {
            return Err(format!(
                "类型 {} 不是类型 {} 的子类型",
                actual_type.to_string(),
                expected_type.to_string()
            ));
        }
        Ok(())
    }

    /// 检查子类型关系（简化实现）
    fn is_subtype(&self, _sub_type: &TypeInfo, _super_type: &TypeInfo) -> bool {
        // 简化实现：总是返回true
        true
    }
}

/// 约束规则trait
trait ConstraintRule {
    /// 检查约束
    #[allow(dead_code)]
    fn check(&self, actual_type: &TypeInfo, constraint: &TypeConstraint) -> Result<(), String>;
}

/// 类型边界规则
struct TypeBoundRule;

impl ConstraintRule for TypeBoundRule {
    fn check(&self, _actual_type: &TypeInfo, _constraint: &TypeConstraint) -> Result<(), String> {
        Ok(())
    }
}

/// 接口规则
struct InterfaceRule;

impl ConstraintRule for InterfaceRule {
    fn check(&self, _actual_type: &TypeInfo, _constraint: &TypeConstraint) -> Result<(), String> {
        Ok(())
    }
}

/// 特质规则
struct TraitRule;

impl ConstraintRule for TraitRule {
    fn check(&self, _actual_type: &TypeInfo, _constraint: &TypeConstraint) -> Result<(), String> {
        Ok(())
    }
}

/// 相等规则
struct EqualRule;

impl ConstraintRule for EqualRule {
    fn check(&self, actual_type: &TypeInfo, constraint: &TypeConstraint) -> Result<(), String> {
        if let TypeConstraint::Equal(expected_type) = constraint {
            if actual_type != expected_type {
                return Err(format!(
                    "类型 {} 与期望类型 {} 不相等",
                    actual_type.to_string(),
                    expected_type.to_string()
                ));
            }
        }
        Ok(())
    }
}

/// 子类型规则
struct SubtypeRule;

impl ConstraintRule for SubtypeRule {
    fn check(&self, actual_type: &TypeInfo, constraint: &TypeConstraint) -> Result<(), String> {
        if let TypeConstraint::Subtype(expected_type) = constraint {
            if actual_type != expected_type {
                return Err(format!(
                    "类型 {} 不是类型 {} 的子类型",
                    actual_type.to_string(),
                    expected_type.to_string()
                ));
            }
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::type_system::type_hierarchy::CompositeType;

    #[test]
    fn test_generic_system_creation() {
        let mut system = GenericSystem::new();

        // 创建泛型类型
        let generic_type = GenericType {
            name: "列表".to_string(),
            parameters: vec![GenericParameter {
                name: "T".to_string(),
                constraints: vec![],
                default: None,
                location: None,
            }],
            definition: TypeDefinition::Composite(CompositeType::List(Box::new(
                TypeDefinition::Basic(BasicType::Any),
            ))),
            location: None,
        };

        // 定义泛型类型
        assert!(system.define_generic_type(generic_type).is_ok());

        // 检查是否已定义
        assert!(system.get_generic_type("列表").is_some());
    }

    #[test]
    fn test_generic_instantiation() {
        let mut system = GenericSystem::new();

        // 创建并定义泛型类型
        let generic_type = GenericType {
            name: "列表".to_string(),
            parameters: vec![GenericParameter {
                name: "T".to_string(),
                constraints: vec![],
                default: None,
                location: None,
            }],
            definition: TypeDefinition::Composite(CompositeType::List(Box::new(
                TypeDefinition::Basic(BasicType::Any),
            ))),
            location: None,
        };

        system.define_generic_type(generic_type).unwrap();

        // 实例化泛型类型
        let mut type_args = HashMap::new();
        type_args.insert(
            "T".to_string(),
            TypeInfo::Basic(crate::interpreter::method::MethodType::Number),
        );

        let result = system.instantiate_generic("列表", type_args, None);
        assert!(result.is_ok());
    }

    #[test]
    fn test_type_constraint_checker() {
        let checker = TypeConstraintChecker::new();
        let system = GenericSystem::new();

        let actual_type = TypeInfo::Basic(crate::interpreter::method::MethodType::Number);
        let constraint = TypeConstraint::Equal(TypeInfo::Basic(
            crate::interpreter::method::MethodType::Number,
        ));

        assert!(
            checker
                .check_constraint(&actual_type, &constraint, &system)
                .is_ok()
        );
    }
}
